using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Reflection;

using NBusiness.ESharp;
using NBusiness.CodeDom;
using NBusiness;

using NBusiness.ESharp.Compiler;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NBusiness.ESharp.Testing.Properties;
using NBusiness.CodeDom.Compiler;
using NBusiness.ESharp.Testing.Mocks;
using NBusiness.CodeDom.Services;

namespace NBusiness.ESharp.Testing
{
	[TestClass]
	public class BasicTests
	{
		[TestMethod]
        public void ParseTestEntity1()
        {
            ESharpProvider provider = new ESharpProvider();
            MockBuildErrorService errorService = new MockBuildErrorService();
            MockTypeFinder typeFinderService = new MockTypeFinder();
            provider.SetService(typeof(IBuildErrorService), errorService);

            EntityRoot root = provider.GetParser().ParseFiles(
                new EntityFile ("Default.Person.es", Resources.Default_Person ));

            Assert.AreEqual(0, errorService.Errors.Count);

            Assert.AreEqual(1, root.Families.Count);
            Assert.AreEqual("Default", root.Families["Default"].Name);

            Assert.AreEqual(1, root.Families["Default"].Entities.Count);
            Assert.AreEqual("Person", root.Families["Default"].Entities[0].Name);

            Assert.AreEqual(4, root.Families["Default"].Entities[0].Fields.Count);

            Assert.AreEqual(typeof(System.Int32), root.Families["Default"].Entities[0].Fields[0].Type);
            Assert.AreEqual(typeof(System.String), root.Families["Default"].Entities[0].Fields[1].Type);
            Assert.AreEqual(typeof(int?), root.Families["Default"].Entities[0].Fields[2].Type);
            Assert.AreEqual(typeof(string), root.Families["Default"].Entities[0].Fields[3].Type);

            Assert.AreEqual("PersonId", root.Families["Default"].Entities[0].Fields[0].Name);
            Assert.AreEqual("Name", root.Families["Default"].Entities[0].Fields[1].Name);
            Assert.AreEqual("Age", root.Families["Default"].Entities[0].Fields[2].Name);
            Assert.AreEqual("Race", root.Families["Default"].Entities[0].Fields[3].Name);

            Assert.IsTrue(root.Families["Default"].Entities[0].Fields[0].IsAuto);
            Assert.IsFalse(root.Families["Default"].Entities[0].Fields[1].IsAuto);
            Assert.IsFalse(root.Families["Default"].Entities[0].Fields[2].IsAuto);
            Assert.IsFalse(root.Families["Default"].Entities[0].Fields[3].IsAuto);

            Assert.IsFalse(root.Families["Default"].Entities[0].Fields[0].IsNullable);
            Assert.IsTrue(root.Families["Default"].Entities[0].Fields[1].IsNullable);
            Assert.IsTrue(root.Families["Default"].Entities[0].Fields[2].IsNullable);
            Assert.IsFalse(root.Families["Default"].Entities[0].Fields[3].IsNullable);

            Assert.IsTrue(root.Families["Default"].Entities[0].Fields[0].IsId);
            Assert.IsFalse(root.Families["Default"].Entities[0].Fields[1].IsId);
            Assert.IsFalse(root.Families["Default"].Entities[0].Fields[2].IsId);
            Assert.IsFalse(root.Families["Default"].Entities[0].Fields[3].IsId);

            Assert.IsTrue(root.Families["Default"].Entities[0].Fields[0].IsReadOnly);
            Assert.IsFalse(root.Families["Default"].Entities[0].Fields[1].IsReadOnly);
            Assert.IsFalse(root.Families["Default"].Entities[0].Fields[2].IsReadOnly);
            Assert.IsTrue(root.Families["Default"].Entities[0].Fields[3].IsReadOnly);
        }

		[TestMethod]
		public void ParseTestEntity2()
		{
            ESharpProvider provider = new ESharpProvider();
            MockBuildErrorService errorService = new MockBuildErrorService();
            MockTypeFinder typeFinderService = new MockTypeFinder();
            provider.SetService(typeof(IBuildErrorService), errorService);

            EntityRoot root = provider.GetParser().ParseFiles(
                new EntityFile ("Default.Person.es", Resources.Default_Person ),
                new EntityFile ("Default.Address.es", Resources.Default_Address ));

            Assert.AreEqual(0, errorService.Errors.Count);

            Assert.AreEqual(1, root.Families.Count);
            Assert.AreEqual("Default", root.Families["Default"].Name);

            Assert.AreEqual(2, root.Families["Default"].Entities.Count);
            Assert.AreEqual("Person", root.Families["Default"].Entities[0].Name);
            Assert.AreEqual("Address", root.Families["Default"].Entities[1].Name);

            Assert.AreEqual(4, root.Families["Default"].Entities[0].Fields.Count);
            Assert.AreEqual(typeof(System.Int32), root.Families["Default"].Entities[0].Fields[0].Type);
            Assert.AreEqual(typeof(System.String), root.Families["Default"].Entities[0].Fields[1].Type);
            Assert.AreEqual(typeof(int?), root.Families["Default"].Entities[0].Fields[2].Type);
            Assert.AreEqual(typeof(string), root.Families["Default"].Entities[0].Fields[3].Type);

            Assert.AreEqual("PersonId", root.Families["Default"].Entities[0].Fields[0].Name);
            Assert.AreEqual("Name", root.Families["Default"].Entities[0].Fields[1].Name);
            Assert.AreEqual("Age", root.Families["Default"].Entities[0].Fields[2].Name);
            Assert.AreEqual("Race", root.Families["Default"].Entities[0].Fields[3].Name);

            Assert.IsTrue(root.Families["Default"].Entities[0].Fields[0].IsId);
            Assert.IsFalse(root.Families["Default"].Entities[0].Fields[1].IsId);
            Assert.IsFalse(root.Families["Default"].Entities[0].Fields[2].IsId);
            Assert.IsFalse(root.Families["Default"].Entities[0].Fields[3].IsId);

            Assert.IsTrue(root.Families["Default"].Entities[0].Fields[0].IsReadOnly);
            Assert.IsFalse(root.Families["Default"].Entities[0].Fields[1].IsReadOnly);
            Assert.IsFalse(root.Families["Default"].Entities[0].Fields[2].IsReadOnly);
            Assert.IsTrue(root.Families["Default"].Entities[0].Fields[3].IsReadOnly);

            Assert.AreEqual(3, root.Families["Default"].Entities[1].Fields.Count);
            Assert.AreEqual(typeof(System.Int32), root.Families["Default"].Entities[1].Fields[0].Type);
            Assert.AreEqual(typeof(System.Int32), root.Families["Default"].Entities[1].Fields[1].Type);
            Assert.AreEqual(typeof(System.String), root.Families["Default"].Entities[1].Fields[2].Type);

            Assert.AreEqual("AddressId", root.Families["Default"].Entities[1].Fields[0].Name);
            Assert.AreEqual("PersonId", root.Families["Default"].Entities[1].Fields[1].Name);
            Assert.AreEqual("Street1", root.Families["Default"].Entities[1].Fields[2].Name);

            Assert.IsTrue(root.Families["Default"].Entities[1].Fields[0].IsId);
            Assert.IsFalse(root.Families["Default"].Entities[1].Fields[1].IsId);
            Assert.IsFalse(root.Families["Default"].Entities[1].Fields[2].IsId);

            Assert.IsTrue(root.Families["Default"].Entities[1].Fields[0].IsReadOnly);
            Assert.IsFalse(root.Families["Default"].Entities[1].Fields[1].IsReadOnly);
            Assert.IsFalse(root.Families["Default"].Entities[1].Fields[2].IsReadOnly);

            Assert.AreEqual(1, root.Families["Default"].Entities[0].Relationships.Count);
            Assert.AreEqual(1, root.Families["Default"].Entities[1].Relationships.Count);
            Assert.AreSame(root.Families["Default"].Entities[0], root.Families["Default"].Entities[1].Relationships[0].With);

            Assert.IsTrue(root.Families["Default"].Entities[1].Relationships[0].On.ContainsKey(root.Families["Default"].Entities[1].Fields[1]));
            Assert.AreSame(root.Families["Default"].Entities[0].Fields[0], root.Families["Default"].Entities[0].Relationships[0].On[root.Families["Default"].Entities[1].Fields[1]]);

            Assert.AreEqual(EntityRelationshipType.Parent, root.Families["Default"].Entities[0].Relationships[0].Type);
		}

        [TestMethod]
        public void ParseExtendedFamily()
        {
            ESharpProvider provider = new ESharpProvider();
            MockBuildErrorService errorService = new MockBuildErrorService();
            MockTypeFinder typeFinderService = new MockTypeFinder();
            provider.SetService(typeof(IBuildErrorService), errorService);

            EntityRoot root = provider.GetParser().ParseFiles(
                new EntityFile ("Extended.Family.Test.es", Resources.Extended_Family_Test ));

            Assert.AreEqual(0, errorService.Errors.Count);

            Assert.AreEqual(1, root.Families.Count);
            Assert.AreEqual(0, root.Families["Extended"].Entities.Count);

            Assert.AreEqual(1, root.Families["Extended"].Families.Count);
            Assert.AreEqual(0, root.Families["Extended"].Families["Family"].Entities.Count);

            Assert.AreEqual(0, root.Families["Extended"].Families["Family"].Families["Deep"].Families.Count);
            Assert.AreEqual(1, root.Families["Extended"].Families["Family"].Families["Deep"].Entities.Count);
            Assert.AreEqual("Test", root.Families["Extended"].Families["Family"].Families["Deep"].Entities[0].Name);
            Assert.AreEqual(2, root.Families["Extended"].Families["Family"].Families["Deep"].Entities[0].Fields.Count);
            Assert.AreEqual("TestId", root.Families["Extended"].Families["Family"].Families["Deep"].Entities[0].Fields[0].Name);
            Assert.AreEqual("Val", root.Families["Extended"].Families["Family"].Families["Deep"].Entities[0].Fields[1].Name);
        }


	}
}
